package com.king.designpatterns.行为模式.策略模式;

/**
 * 策略模式（Strategy Pattern）也叫政策模式，是一种比较简单的模式。
 *
 * 定义：定义一组算法，将每个算法都封装起来，并且使它们之间可以互换。
 *
 * 角色：
 *      ■ 环境（Context）角色：
 *          该角色也叫上下文角色，起到承上启下的作用，屏蔽高层模块对策略、算法的直接访问，它持有一个Strategy类的引用。
 *      ■ 抽象策略（Strategy）角色：
 *          该角色对策略、算法进行抽象，通常定义每个策略或算法必须具有的方法和属性。
 *      ■ 具体策略（Concrete Strategy）角色：
 *          该角色实现抽象策略中的具体操作，含有具体的算法。
 *
 * 优缺点：
 *      优点：
 *          ■ 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族，恰当地使用继承可以把公共的代码移到父类中，
 *              从而避免代码重复。
 *          ■ 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为，如果不用策略模式，那么使用算法或行为的环境类就可能会有一些子类，
 *              每一个子类提供一个不同的算法或行为。但是，这样算法或行为的使用者就和算法本身混在一起，从而不可能再独立演化。
 *          ■ 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护，
 *              它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起，统统列在一个多重转移语句里面，这比使用继承的办法还要原始和落后。
 *      缺点：
 *          ■ 客户端必须知道所有的策略类，并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别，
 *              以便适时选择恰当的算法类，即策略模式只适用于客户端知道所有的算法或行为的情况。
 *          ■ 策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保持到客户端里面，而将策略类设计成可共享的，
 *              这样策略类实例可以被不同客户端使用。可以使用享元模式来减少对象的数量。
 *
 * 场景：
 *      ■ 多个类只是在算法或行为上稍有不同的场景。
 *      ■ 算法需要自由切换的场景。
 *      ■ 需要屏蔽算法规则的场景。
 *
 * @author king
 * @date 2021-06-10 15:57
 */
public class StrategyPattern {
    public static void main(String[] args) {
        ContextClient context0 = new ContextClient(new NoDiscountStrategy(48.5, 20));
        System.out.println("0折扣：" + context0.contextCalDisc());
        ContextClient contextFix = new ContextClient(new FixDiscountStrategy(48.5, 20));
        System.out.println("固定折扣：" + contextFix.contextCalDisc());
        ContextClient contextPer = new ContextClient(new PercentageDiscountStrategy(48.5, 20));
        System.out.println("15%折扣：" + contextPer.contextCalDisc());
    }
}
